﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using log4net;
using log4net.Config;
using log4net.Appender;
using log4net.Repository.Hierarchy;
using System.Reflection;

namespace FinPlusAssembler
{
    public enum Level { Debug, Info, Warning, Error, Fatal }

    public static class Logger 
    {
        public static string Path;
        private static string _name = "finplus";
        private volatile static bool _isInitialized;
        private volatile static object _lock = new object();
        
        public static List<Level> _enabled;

        //public
        public static bool Log(this Level level, string message) { return Log(level, "NA", "NA", message, new Exception("NA")); }

        public static bool Log(this Level level, string message, Exception exception) { return level.Log("NA", "NA", message, exception); }

        public static bool Log(this Level level, string id, string config, string message, Exception exception)
        {
            Initialise();

            var log = LogManager.GetLogger(_name);
            
            if (log != null && IsEnabled(log, level))
            {
                var info = string.Format("{0}@{1}@{2}", id ?? "NA", config ?? "NA", message);

                switch (level)
                {
                    case Level.Debug: log.Debug(info, exception); break;
                    case Level.Info: log.Info(info, exception); break;
                    case Level.Warning: log.Warn(info, exception); break;
                    case Level.Error: log.Error(info, exception); break;
                    case Level.Fatal: log.Fatal(info, exception); break;
                }
            }

            return false;
        }

        //private
        private static void Initialise()
        {
            if (!_isInitialized)
            {
                lock (_lock)
                    if (!_isInitialized)
                    {
                        XmlConfigurator.ConfigureAndWatch(new FileInfo(Assembly.GetExecutingAssembly().ConfigPath()));
                        var rootAppender = ((Hierarchy)LogManager.GetRepository()).Root.Appenders.OfType<FileAppender>().FirstOrDefault();
                        Path = rootAppender  == null ? rootAppender.File : string.Empty;                      
                        _isInitialized = true;
                    }
            }
        }

        private static bool IsEnabled(ILog log, Level level)
        {
            switch (level)
            {
                case Level.Debug: return log.IsDebugEnabled;
                case Level.Info: return log.IsInfoEnabled;
                case Level.Warning: return log.IsWarnEnabled;
                case Level.Error: return log.IsErrorEnabled;
                case Level.Fatal: return log.IsFatalEnabled;
                default: return false;
            }
        }
    }
}

